
/***************************************************
 DFRobot Gravity: HCHO Sensor
 <https://www.dfrobot.com/wiki/index.php/Gravity:_HCHO_Sensor_SKU:_SEN0231>

 ****************************************************/
#define BLINKER_WIFI
#include "DHTesp.h"
#include <Blinker.h>
#include <DFRobotHCHOSensor.h>
#include <SoftwareSerial.h>
#include <ESP8266WiFi.h>
#include <ESP8266WiFiMulti.h>

void smartConfig()
{
WiFi.mode(WIFI_STA);
Serial.println("\r\nWait for Smartconfig");
WiFi.beginSmartConfig();
while (!WiFi.smartConfigDone()) {
Serial.print(".");
delay(500);
}
Serial.println("SmartConfig Success");
Serial.printf("SSID:%s\r\n", WiFi.SSID().c_str());
Serial.printf("PSW:%s\r\n", WiFi.psk().c_str());
wifiMulti.addAP(WiFi.SSID().c_str(),WiFi.psk().c_str());
}

// FOR APRS
#define CALLSIGN "BGnXXX-11"// Change to your callsign
#define PASSCODE "xxxxx" // GENERATE IT ON apps.magicbug.co.uk/passcode/
#define LATITUDE "xxxx.04N" // LOOK !! -> 4 DIGITS POINT 2 DIGITS
#define LONGITUDE "xxxxx.55E" // LOOK !! -> 5 DIGITS POINT 2 DIGITS
#define SERVER_NAME "china.aprs2.net"
#define PORT 14580
#define SensorSerialPin  12  //this pin read the uart signal from the HCHO sensor


SoftwareSerial sensorSerial(SensorSerialPin,SensorSerialPin);

DFRobotHCHOSensor hchoSensor(&sensorSerial);
#include <LiquidCrystal_I2C.h>
LiquidCrystal_I2C lcd(0x3F,16,2);  // set the LCD address to 0x27 for a 16 chars and 2 line display
//D2-SDA D1-Scl
   DHTesp dht; 
#define DHTTYPE DHT11   // DHT 11
#define Aout A0 
int temp=0; //读取A0

float sinVal;            
int toneVal;
int W=0;
void sendAPRS(){
    WiFiClient client;
    int retr=20;
    while(!client.connect(SERVER_NAME, PORT) && retr>0){
      delay(50);
      --retr;
    }
    if(client.connected()){ // CONNECTED TO THE HOST
      Serial.println("APRS server connected !");
      /*********************************************** 
       *            APRS AUTHENTICATION              *
       ***********************************************/
      client.print("user ");
      client.print(CALLSIGN);
      client.print(" pass ");
      client.print(PASSCODE);
      client.print(" vers ESP8266WX 1.0 UDP 8888\n");
      /*********************************************** 
       *               SEND APRS DATA                *
       ***********************************************/
      Serial.println("Sending...");
      client.print(CALLSIGN);
      client.print(">APUVR,TCPIP*:=");
      client.print(LATITUDE);
      client.print("/");
      client.print(LONGITUDE);
      client.print("_.../...g...t0");
      client.print((int)dht.getTemperature()*9/5+32);
      client.print("r...p...h");
      client.print((int)dht.getHumidity());
      client.print("b10153HCHO");
      client.print(hchoSensor.uartReadPPM());
      client.print("PPM  ESP8266WX 欢迎来到嘉兴");
      client.print("\r\n");
     /*********************************************** 
      *              CLOSE CONNECTION               *
      ***********************************************/
      Serial.println("Done !");
      client.stop();
      
    }else{ // CONNECTION FAILURE
      Serial.println("Can't connect to the server (APRS)");
      client.stop();
    }
}
/*****************************************************/

const uint32_t connectTimeoutMs = 5000;

int count=0;
//bool WIFI_Status = true;
bool AutoConfig()
{
  WiFi.begin();
  for (int i=0; i<20; i++)
  {
    int wstatus = WiFi.status();
    if (wstatus == WL_CONNECTED )  
       {
          Serial.println("wifi smartConfig success");
          Serial.printf("SSID:%s",WiFi.SSID().c_str());
          Serial.printf(",PWS:%s\r\n",WiFi.psk().c_str());
          Serial.print("localIP:");
          Serial.println(WiFi.localIP());
          Serial.print(",GateIP:");
          Serial.println(WiFi.gatewayIP());
          return true;
          
       }
       else
       {
          Serial.print("WIFI AutoConfig Waiting ....");
          Serial.println(wstatus);
          delay(1000);
        
       }
    
  }
  Serial.println("Wifi autoconfig faild!");
  return false;
  
  
}


//----------------------------------------------//

void setup()
{  
    sensorSerial.begin(9600); //the baudrate of HCHO is 9600
    sensorSerial.listen();
    Serial.begin(9600);
  dht.setup(2, DHTesp::DHT11); // Connect DHT sensor to GPIO 
   // dht.begin();
    lcd.begin(16,2);                      // initialize the lcd 
  lcd.init();
    // Print a message to the LCD.
  lcd.backlight();
 pinMode(15, OUTPUT);
pinMode(Aout,INPUT);
    Serial.println();
      pinMode(LED_BUILTIN, OUTPUT);
  Serial.print("Connecting to ");
 //  lcd.print("Connecting to ");
Serial.println("\r\n正在连接");
    lcd.print("connecting...");
    //当设备没有联网的情况下，执行下面的操作
    
    delay(1000);
if (!AutoConfig())
  {
    smartConfig();
  }
  
  Serial.println("WiFi connected");
  lcd.print("WiFi connected");
  
    Serial.println("IP address: ");
    Serial.println(WiFi.localIP());
  }


void loop()
{   
    if(hchoSensor.available()>0)  
  {
    {
      Serial.print(hchoSensor.uartReadPPM());
      Serial.println("ppm");
     float HCHO = (hchoSensor.uartReadPPM());
       lcd.noBlink();
     lcd.setCursor(0,0);
     lcd.print("HCHO:");
//    lcd.print(HCHO);
 //   lcd.print("ppm");

 //    lcd.setCursor(5,1);
     lcd.print(HCHO*1.34);//  Unit conversion ：1pp     m = 1.34 mg/m3  
     lcd.print("mg/m3");
       lcd.setCursor(0,1);
       lcd.print(HCHO);
           lcd.print("ppm");
      Serial.println(W);
      lcd.setCursor(13,1);
      lcd.print(W);
  if(HCHO<0.06)
     {
      lcd.setCursor(8,1);
    lcd.print("SAFE");
    noTone(15);
     }
     else if(HCHO<0.2)
    { 
      lcd.setCursor(4,1);
      lcd.print("WARNING");
            for(int x=0; x<180; x++){
                        //将sin函数角度转化为弧度
                        sinVal = (sin(x*(3.1412/180)));
                       //用sin函数值产生声音的频率
                       toneVal = 2000+(int(sinVal*1000));
                      //给引脚8一个
                       tone(15, toneVal);
                       delay(2);
}
    }
    else if(HCHO<4)
    {
      lcd.setCursor(4,1);
      lcd.print("DANGER");
            for(int x=0; x<180; x++){
                        //将sin函数角度转化为弧度
                        sinVal = (sin(x*(3.1412/180)));
                       //用sin函数值产生声音的频率
                       toneVal = 2000+(int(sinVal*1000));
                      //给引脚8一个
                       tone(15, toneVal);
                       delay(2);
    }
    delay(5000);
    }
    delay(5000);
    lcd.clear();
    }

       float humidity = dht.getHumidity();
       float temperature = dht.getTemperature();
         float temperature2 = dht.getTemperature()*9/5+32;
      if (isnan(humidity) || isnan(temperature)) {
        Serial.print("Failed to read from DHT sensor!");
        return;
    }
     delay(dht.getMinimumSamplingPeriod());
    lcd.setCursor(0,0);
    lcd.print("Humi:");
    lcd.print(humidity, 1);
    lcd.print("%");
    lcd.setCursor(0,1);
    lcd.print("Temp:");
    lcd.print(temperature, 1);
    lcd.print("C/");
    lcd.print(temperature2, 1);
    lcd.print("F");
    delay(5000);
    lcd.clear();
     Serial.println(humidity);
      Serial.println(temperature);
    
    
 
//------------------------------------MQ0----//
 temp = analogRead(Aout); //读取A0的模拟数据  
 lcd.print("Index:");
 lcd.print(temp);
  if (temp>70)
    {

      lcd.setCursor(4,1);
      lcd.print("Fire WARNING");
            for(int x=0; x<180; x++){
                        //将sin函数角度转化为弧度
                        sinVal = (sin(x*(3.1412/180)));
                       //用sin函数值产生声音的频率
                       toneVal = 2000+(int(sinVal*1000));
                      //给引脚8一个
                       tone(15, toneVal);
                       delay(2);
    }
    }
   else{
    lcd.setCursor(4,1);
    lcd.print("Fire SAFE");
    noTone(15);
    }
  Serial.println(temp); //串口输出temp的数据  


    delay(5000);
      lcd.clear();
      if(W<20)
     W++;
      else
       {
        lcd.setCursor(4,1);
        lcd.print("APRS sending");
        sendAPRS();
        delay(1000);
        W=0;
       }
      lcd.clear();
    }

}
